Виджеты. Card
➡️ Скачать презентацию. Flutter Card
➡️ Ссылка на репозиторий с кодом этого урока
Создание карточки Card Material 3
Виджет Card во Flutter используется для отображения элементов в виде карточек с закругленными углами и тенями. Часто используется для отображения связанных элементов (карточки товаров, карточки профиля).
https://m3.material.io/components/cards/guidelines
Основные особенности:
- Карточки имеют тень, что придаёт глубину и выделяет их. Изменение свойства
elevationкарты позволяет контролировать эффект тени. - Закругленные углы создают более современный и эстетичный вид.
Cardиз библиотеки Material содержит связанные фрагменты информации и может быть составлена практически из любого виджета, но часто используется вместе сListTile()- По умолчанию карта сжимает свой размер до 0 на 0 пикселей. Можно использовать
SizedBox, чтобы ограничить размер карты. - Содержимое
Cardне прокручивается
Виджет Card
- В папку
widgetsдобавим файлcard_widget.dart - В файле
card_widget.dartдобавим новый виджетCardExample() - ⭕ В файле
main.dartвнутри виджетаMyApp()в параметрbodyпередаёмCardExample()
import 'package:flutter/material.dart';
class CardExample extends StatelessWidget {
const CardExample({super.key});
@override
Widget build(BuildContext context) {
return Card();
}
}
Основные параметры Card
color: задает цвет карточки.
elevation: регулирует высоту тени. Чем больше значение, тем сильнее тень.
shape: определяет форму карточки, в том числе радиус закругления углов.
margin: отступы вокруг карточки.
child: основной содержимый виджет внутри карточки.
shadowColor: цвет тени, который отображается вокруг карточки.
Примеры использования виджета Card
Простая карточка с текстом.
Карточка имеет базовую тень и закругленные углы по умолчанию.
Файл card_widget.dart
import 'package:flutter/material.dart';
class CardExample extends StatelessWidget {
const CardExample({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Card(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Карточка с текстом',
style: TextStyle(fontSize: 18),
),
),
),
);
}
}

Добавим цвет для карточки и для тени, сделаем карточку выше через elevation
Файл card_widget.dart
Card(
color: Colors.lightBlue[50],
elevation: 10,
shadowColor: Colors.blueAccent,
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Карточка с цветом и тенями',
style: TextStyle(fontSize: 18),
),
),
),

Комплексный пример создания карточки

Файл card_widget.dart
import 'package:flutter/material.dart';
class CardExample extends StatelessWidget {
const CardExample({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Card(
elevation: 2, // Высота тени
color: Colors.white, // Цвет фона карточки
// По умолчанию размеры карточки 0 на 0
// Обернём в SizedBox и укажем размеры вручную
child: SizedBox(
width: 310, // Ширина карточки
child: Column( // Содержимое карточки будет располагаться в колонке
mainAxisSize: MainAxisSize.min, // Высота ужмётся под содержимое
children: [
Image.asset(
'assets/images/fd.png',
),
ListTile(
title: Text("Flutter Конференция"),
subtitle: Text("Самое крутое мероприятие в году"),
)
],
),
),
),
);
}
}

Виджет ClipRRect
Чтобы скруглить верхние углы у изображения нужно его обернуть в виджет ClipRRect()

Он позволяет обрезать (обтекать) дочерний виджет, применяя закругленные углы (borderRadius). Он полезен, когда нужно создать округлые изображения, кнопки или контейнеры.
Основные параметры:
borderRadius: устанавливает радиус скругления углов.
clipBehavior: определяет, как обрезается содержимое.
child: дочерний виджет, который будет обрезан.
.png)
Файл card_widget.dart
class CardExample extends StatelessWidget {
const CardExample({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Card(
elevation: 2, // Высота тени
color: Colors.white, // Цвет фона карточки
// По умолчанию размеры карточки 0 на 0
// Обернём в SizedBox и укажем размеры вручную
child: SizedBox(
width: 310, // Ширина карточки
child: Column(
// Содержимое карточки будет располагаться в колонке
mainAxisSize: MainAxisSize.min, // Высота ужмётся под содержимое
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(12), // Радиус углов сверху слева
topRight: Radius.circular(12), // Радиус углов сверху справа
),
child: Image.asset(
'assets/images/fd.png',
width: double.infinity, // Максимально возможная ширина
height: 180, // Фиксированная высота изображения
fit: BoxFit.cover, // Заполняет все пространство
),
),
ListTile(
title: Text("Flutter Конференция"),
subtitle: Text("Самое крутое мероприятие в году"),
),
],
),
),
),
);
}
}
Виджет ListTile
Удобный виджет для оформления элемента списка. Он объединяет заголовок, подзаголовок, иконки, leading и trailing виджеты в одном элементе.
В ListTile добавим кнопку "Купить билеты"
.png)
Основные параметры:
leading: виджет, который отображается слева (обычно иконка или аватарка).
title: основной заголовок.
subtitle: подзаголовок (второстепенный текст).
trailing: виджет, который справа (обычно иконка или кнопка).
onTap: обработчик нажатия.
tileColor: цвет фона.
shape: форма элемента (например, скругленные углы).
selected: если true, элемент выделяется цветом selectedTileColor.
В subtitle можно передать колонку, в колонке расположить Text и ElevationButton
.png)
Полностью код карточки
Файл card_widget.dart
import 'package:flutter/material.dart';
class CardExample extends StatelessWidget {
const CardExample({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Card(
elevation: 2, // Высота тени
color: Colors.white, // Цвет фона карточки
// По умолчанию размеры карточки 0 на 0
// Обернём в SizedBox и укажем размеры вручную
child: SizedBox(
width: 310, // Ширина карточки
child: Column(
// Содержимое карточки будет располагаться в колонке
mainAxisSize: MainAxisSize.min, // Высота ужмётся под содержимое
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(12), // Радиус углов сверху слева
topRight: Radius.circular(12), // Радиус углов сверху справа
),
child: Image.asset(
'assets/images/fd.png',
width: double.infinity, // Максимально возможная ширина
height: 180, // Фиксированная высота изображения
fit: BoxFit.cover, // Заполняет все пространство
),
),
ListTile(
title: Text("Flutter Конференция"),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Самое крутое мероприятие в году"),
SizedBox(height: 8),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: ElevatedButton(
onPressed: () {},
child: const Text("Купить билеты"),
),
),
],
),
),
],
),
),
),
);
}
}
Виды Card
Есть ещё два вида карточки
- С обводкой
- С заполнением
class CardTypesExample extends StatelessWidget {
const CardTypesExample({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: SizedBox(
width: 320,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Карточка с обводкой Card.outlined
Card.outlined(
child: ListTile(
leading: Icon(Icons.favorite),
title: Text("Карточка с обводкой"),
subtitle: Text("Card.outlined"),
),
),
// Карточка с закрашеным фоном Card.filled
Card.filled(
child: ListTile(
leading: Icon(Icons.favorite),
title: Text("Карточка с заполнением"),
subtitle: Text("Card.filled"),
),
),
],
),
),
);
}
}

Переделаем пример с роллами
class RollCard extends StatelessWidget {
final double height;
const RollCard({super.key, this.height = 220});
@override
Widget build(BuildContext context) {
return SizedBox(
width: 190,
child: Card(
margin: EdgeInsets.all(8),
color: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
child: Image.asset(
"assets/images/sushi.jpg",
width: double.infinity,
height: 100,
fit: BoxFit.cover,
),
),
Expanded(
child: ListTile(
title: Text("Вкусные Роллы"),
subtitle: Text(
"Огурец, креветка, сыр",
style: TextStyle(fontSize: 10),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 6),
child: TextButton(
onPressed: () {},
child: Text("Купить"),
),
),
],
),
),
);
}
}
